/*******************************************************************/
/* @ All Rights Reserved Copyright (C) 2014 broada,Co.,Ltd.        */
/*                                                                 */
/*  NAME      = frcmd_server_l7.c                                  */
/*  NOTE      =                                                    */
/*  DATE      = 2014/12/29 by geyh                                 */
/*******************************************************************/
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>

#include "frcomm.h"
#include "frmem.h"
#include "frlog.h"
#include "frame.h"
#include "client.pb-c.h"
#include "frconfig.h"
#include "conntrack.h"
#include "frproto_mng.h"
#include "frproto_l7default.h"
#include "frame_params.h"
#include "frcmd_server_l7.h"

#define     ARR_L7_SET_MAX_LEN       256
#define     ARR_MODULE_SET_MAX_LEN   256
#define     ARR_FILE_TMP_MAX_LEN     128
#define     ARR_SYS_CMD_MAX_LEN      128

static int __l7_add_file_no_exist(char *p_l7_set)
{
    char arr_file_tmp[ARR_FILE_TMP_MAX_LEN];
    FILE *fp = NULL;
    //构建临时文件文件名
    snprintf(arr_file_tmp,sizeof(arr_file_tmp),"%s_tmp",APM_CFG_FILENAME_ANALYZER);

    fp = fopen(arr_file_tmp,"w");
    if(!fp)
        return FR_FAIL;
    fprintf(fp,"%s=%s",APM_ANALYZER_KEY_PROTOCOLS_LOAD,p_l7_set);
    fclose(fp);
    return FR_SUCC;
}

static int __l7_add_file_exist(char *p_value, char *p_l7_set)
{
    char arr_file_tmp[ARR_FILE_TMP_MAX_LEN];
    char *p_value_tmp = NULL;
    FILE *fp = NULL;

    //判断最后一位是否为";"
    if(*p_value !='\0' && *(p_value + strlen(p_value) - 1) == ';')
    {
        p_value_tmp = frmalloc(strlen(p_value) + strlen(p_l7_set) + 1);
        if(!p_value_tmp)
            return FR_FAIL;
        snprintf(p_value_tmp,strlen(p_value) + strlen(p_l7_set) + 1,"%s%s",p_value,p_l7_set);
    }
    else
    {
        if(*p_value!='\0')
        {
            p_value_tmp = frmalloc(strlen(p_value) + strlen(p_l7_set) + 1 + 1);
            if(!p_value_tmp)
                return FR_FAIL;
            snprintf(p_value_tmp,strlen(p_value) + strlen(p_l7_set) + 1 + 1,"%s;%s",p_value,p_l7_set);
        }
        else
        {
            p_value_tmp = frmalloc(strlen(p_l7_set) + 1);
            if(!p_value_tmp)
                return FR_FAIL;
            snprintf(p_value_tmp, strlen(p_l7_set) + 1,"%s",p_l7_set);
        }
    }
    //构建临时文件文件名
    snprintf(arr_file_tmp,sizeof(arr_file_tmp),"%s_tmp",APM_CFG_FILENAME_ANALYZER);
    fp = fopen(arr_file_tmp,"w");
    if(fp == NULL)
        return FR_FAIL;

    fprintf(fp,"%s=%s", APM_ANALYZER_KEY_PROTOCOLS_LOAD, p_value_tmp);
    frfree(p_value_tmp);
    fclose(fp);

    return FR_SUCC;
}


//服务端add
static int __do_l7_add(L7Setting *l7_settings)
{
    char *p_value = NULL;
    int i_ret = 0;
    char arr_l7_set[ARR_L7_SET_MAX_LEN];
    char arr_file_tmp[ARR_FILE_TMP_MAX_LEN];

    //获取l7_settings
    snprintf(arr_l7_set,sizeof(arr_l7_set),"%s:%s:%s:%s",l7_settings->has_ip_proto ? FR_L4PROTO2STR(l7_settings->ip_proto) :""
            ,int_ntoa(l7_settings->ip),l7_settings->port,l7_settings->l7_proto);

    //构建临时文件文件名
    snprintf(arr_file_tmp,sizeof(arr_file_tmp),"%s_tmp",APM_CFG_FILENAME_ANALYZER);
    //判断临时文件是否存在  如果存在
    if(access(arr_file_tmp,W_OK) == 0)
    {
        i_ret = frconfig_get_string(arr_file_tmp,APM_ANALYZER_KEY_PROTOCOLS_LOAD,&p_value);
        //不存在KEY
        if(i_ret != APM_FRCONFIG_SUCC)
        {
            i_ret = __l7_add_file_no_exist(arr_l7_set);
            return i_ret;
        }
        //key存在
        i_ret = __l7_add_file_exist(p_value,arr_l7_set);
        frfree(p_value);
        return i_ret;
    }
    //临时文集不存在
    i_ret = frconfig_get_string(APM_CFG_FILENAME_ANALYZER,APM_ANALYZER_KEY_PROTOCOLS_LOAD,&p_value);
    //如果原配置文件不存在 或者原文件中不含APM_ANALYZER_KEY_PROTOCOLS_LOAD
    if(i_ret != APM_FRCONFIG_SUCC)
    {
        i_ret = __l7_add_file_no_exist(arr_l7_set);
        return i_ret;
    }

    //原配置文件中存在APM_ANALYZER_KEY_PROTOCOLS_LOAD
    i_ret = __l7_add_file_exist(p_value,arr_l7_set);
    frfree(p_value);

    return i_ret;
}

//服务端commit
int do_l7_commit(void)
{
    char *p_value = NULL;
    char arr_sys_cmd[ARR_SYS_CMD_MAX_LEN];
    int i_ret = 0;
    char arr_file_tmp[ARR_FILE_TMP_MAX_LEN];

    snprintf(arr_file_tmp,sizeof(arr_file_tmp),"%s_tmp",APM_CFG_FILENAME_ANALYZER);
    i_ret = frconfig_get_string(arr_file_tmp, APM_ANALYZER_KEY_PROTOCOLS_LOAD, &p_value);
    if(i_ret != APM_FRCONFIG_SUCC)
        return FR_SUCC;

    i_ret = frconfig_set_string (APM_CFG_FILENAME_ANALYZER, APM_ANALYZER_KEY_PROTOCOLS_LOAD, p_value);
    frfree(p_value);

    if(i_ret == FR_SUCC)
    {
        snprintf(arr_sys_cmd,sizeof(arr_sys_cmd),"rm %s",arr_file_tmp);
        system(arr_sys_cmd);
        i_ret = frproto_cfg_load(FR_YES);
        return i_ret;
    }

    return FR_FAIL;
}

int do_l7_default_commit(void)
{
    char *p_value = NULL;
    char arr_sys_cmd[ARR_SYS_CMD_MAX_LEN];
    int i_ret = 0;
    char arr_file_tmp[ARR_FILE_TMP_MAX_LEN];

    snprintf(arr_file_tmp,sizeof(arr_file_tmp),"%s_tmp2",APM_CFG_FILENAME_ANALYZER);
    i_ret = frconfig_get_string(arr_file_tmp, APM_ANALYZER_KEY_L7_DEFAULT, &p_value);
    if(i_ret != APM_FRCONFIG_SUCC)
        return FR_SUCC;

    i_ret = frconfig_set_string (APM_CFG_FILENAME_ANALYZER, APM_ANALYZER_KEY_PROTOCOLS_LOAD, p_value);
    frfree(p_value);

    if(i_ret == FR_SUCC)
    {
        snprintf(arr_sys_cmd,sizeof(arr_sys_cmd),"rm %s",arr_file_tmp);
        system(arr_sys_cmd);
        i_ret = frproto_l7default_load(FR_YES);
        return i_ret;
    }

    return FR_FAIL;
}

//服务端rollback
int do_l7_rollback(void)
{
    char arr_sys_cmd[ARR_SYS_CMD_MAX_LEN];

    snprintf(arr_sys_cmd,sizeof(arr_sys_cmd),"rm %s_tmp",APM_CFG_FILENAME_ANALYZER);
    system(arr_sys_cmd);
    return FR_SUCC;
}

int do_l7_default_rollback(void)
{
    char arr_sys_cmd[ARR_SYS_CMD_MAX_LEN];

    snprintf(arr_sys_cmd,sizeof(arr_sys_cmd),"rm %s_tmp2",APM_CFG_FILENAME_ANALYZER);
    system(arr_sys_cmd);
    return FR_SUCC;
}

static int __do_l7_del(L7Setting *l7_settings)
{
    char *p_value = NULL;
    FILE *fp = NULL;
    int i_ret = 0;
    char arr_l7_set[ARR_L7_SET_MAX_LEN];
    char arr_file_tmp[ARR_FILE_TMP_MAX_LEN];
    char *p_tmp = NULL;
    char *p = NULL;

    //获取l7_settings
    if(l7_settings->l7_proto)
    {
        snprintf(arr_l7_set,sizeof(arr_l7_set),"%s:%s:%s:%s",l7_settings->has_ip_proto ? FR_L4PROTO2STR(l7_settings->ip_proto) :""
                ,int_ntoa(l7_settings->ip),l7_settings->port,l7_settings->l7_proto);
    }
    else
    {
        snprintf(arr_l7_set,sizeof(arr_l7_set),"%s:%s:%s",l7_settings->has_ip_proto ? FR_L4PROTO2STR(l7_settings->ip_proto) :""
                ,int_ntoa(l7_settings->ip),l7_settings->port);
    }

    //构建临时文件文件名
    snprintf(arr_file_tmp,sizeof(arr_file_tmp),"%s_tmp",APM_CFG_FILENAME_ANALYZER);
    //判断临时文件是否存在  如果存在
    if(access(arr_file_tmp,W_OK) == 0)
    {
        i_ret = frconfig_get_string(arr_file_tmp,APM_ANALYZER_KEY_PROTOCOLS_LOAD,&p_value);
        if(i_ret != APM_FRCONFIG_SUCC || *p_value =='\0')
        {
            if(p_value)
                frfree(p_value);
            return FR_SUCC;
        }

        p_tmp = strstr(p_value,arr_l7_set);
        if(!p_tmp)
        {
            frfree(p_value);
            return FR_SUCC;
        }
        while(p_tmp)
        {
            //要删除的规则之后的字符串往前移，覆盖要删除的规则
            p = strchr(p_tmp,';');
            p = p? (p+1):(p_tmp + strlen(p_tmp));
            memmove(p_tmp, p, strlen(p) + 1);
            p_tmp = strstr(p_value,arr_l7_set);
        }
        fp = fopen(arr_file_tmp,"w");
        if(!fp)
        {
            frfree(p_value);
            return FR_FAIL;
        }
        fprintf(fp,"%s=%s",APM_ANALYZER_KEY_PROTOCOLS_LOAD,p_value);
        frfree(p_value);
        fclose(fp);
        return FR_SUCC;
    }

    //临时文件不存在
    //如果原配置文件存在 则获取原文件中的value值
    i_ret = frconfig_get_string(APM_CFG_FILENAME_ANALYZER,APM_ANALYZER_KEY_PROTOCOLS_LOAD,&p_value);
    if(i_ret != APM_FRCONFIG_SUCC)
        return FR_SUCC;

    p_tmp = strstr(p_value,arr_l7_set);
    if(!p_tmp)
    {
        frfree(p_value);
        return FR_SUCC;
    }
    while(p_tmp)
    {
        //要删除的规则之后的字符串往前移，覆盖要删除的规则
        p = strchr(p_tmp,';');
        p = p? (p+1):(p_tmp + strlen(p_tmp));
        memmove(p_tmp, p, strlen(p) + 1);
        p_tmp = strstr(p_value,arr_l7_set);
        p_tmp = strstr(p_value,arr_l7_set);
    }

    fp = fopen(arr_file_tmp,"w");
    if(!fp)
    {
        frfree(p_value);
        return FR_FAIL;
    }
    fprintf(fp,"%s=%s",APM_ANALYZER_KEY_PROTOCOLS_LOAD,p_value);
    frfree(p_value);
    fclose(fp);
    return FR_SUCC;
}

static int __do_l7_clear(void)
{
    int i_ret = 0;
    char arr_file_tmp[ARR_FILE_TMP_MAX_LEN];
    FILE *fp = NULL;
    //构建临时文件名
    snprintf(arr_file_tmp, ARR_FILE_TMP_MAX_LEN, "%s_tmp", APM_CFG_FILENAME_ANALYZER);
    //如果临时文件不存在，则建立一个空文件
    if(access(arr_file_tmp,W_OK) == -1)
    {
        fp = fopen(arr_file_tmp,"w");
        fclose(fp);
    }
    i_ret = frconfig_set_string(arr_file_tmp,APM_ANALYZER_KEY_PROTOCOLS_LOAD,"\0");
    return i_ret;
}

int do_l7_cmd(Command *p_command)
{
    L7Command *l7_cmd = p_command->l7_cmd;
    char *p_action = l7_cmd->action;
    int i_ret = 0;

    if (p_action == NULL)
        return FR_FAIL;

    if (strncasecmp(p_action, "add", strlen("add")) == 0)
    {
        frdbg("__do_l7_add start\n");
        L7Setting *l7_settings = l7_cmd->l7_settings[0];
        i_ret = __do_l7_add(l7_settings);
        return i_ret;
    }
    else if (strncasecmp(p_action, "del", strlen("del")) == 0)
    {
        frdbg("__do_l7_del start\n");
        L7Setting *l7_settings = l7_cmd->l7_settings[0];
        i_ret = __do_l7_del(l7_settings);
        return i_ret;
    }
    else if (strncasecmp(p_action, "clear", strlen("clear")) == 0)
    {
        frdbg("__do_l7_clear start\n");
        i_ret = __do_l7_clear();
        return i_ret;
    }
    else
        return FR_FAIL;
}


static int __l7default_add_file_no_exist(char *p_l7_set)
{
    char arr_file_tmp[ARR_FILE_TMP_MAX_LEN];
    FILE *fp = NULL;
    //构建临时文件文件名
    snprintf(arr_file_tmp,sizeof(arr_file_tmp),"%s_tmp2",APM_CFG_FILENAME_ANALYZER);

    fp = fopen(arr_file_tmp,"w");
    if(!fp)
        return FR_FAIL;
    fprintf(fp,"%s=%s",APM_ANALYZER_KEY_L7_DEFAULT,p_l7_set);
    fclose(fp);
    return FR_SUCC;
}

static int __l7default_add_file_exist(char *p_value, char *p_l7_set)
{
    char arr_file_tmp[ARR_FILE_TMP_MAX_LEN];
    char *p_value_tmp = NULL;
    FILE *fp = NULL;

    //判断最后一位是否为";"
    if(*p_value !='\0' && *(p_value + strlen(p_value) - 1) == ';')
    {
        p_value_tmp = frmalloc(strlen(p_value) + strlen(p_l7_set) + 1);
        if(!p_value_tmp)
            return FR_FAIL;
        snprintf(p_value_tmp,strlen(p_value) + strlen(p_l7_set) + 1,"%s%s",p_value,p_l7_set);
    }
    else
    {
        if(*p_value!='\0')
        {
            p_value_tmp = frmalloc(strlen(p_value) + strlen(p_l7_set) + 1 + 1);
            if(!p_value_tmp)
                return FR_FAIL;
            snprintf(p_value_tmp,strlen(p_value) + strlen(p_l7_set) + 1 + 1,"%s;%s",p_value,p_l7_set);
        }
        else
        {
            p_value_tmp = frmalloc(strlen(p_l7_set) + 1);
            if(!p_value_tmp)
                return FR_FAIL;
            snprintf(p_value_tmp, strlen(p_l7_set) + 1,"%s",p_l7_set);
        }
    }
    //构建临时文件文件名
    snprintf(arr_file_tmp,sizeof(arr_file_tmp),"%s_tmp2",APM_CFG_FILENAME_ANALYZER);
    fp = fopen(arr_file_tmp,"w");
    if(fp == NULL)
        return FR_FAIL;

    fprintf(fp,"%s=%s", APM_ANALYZER_KEY_L7_DEFAULT, p_value_tmp);
    frfree(p_value_tmp);
    fclose(fp);

    return FR_SUCC;
}


//服务端add
static int __l7_default_add(int ip_proto, char *l7_proto, int i_mem_size)
{
    char *p_value = NULL;
    int i_ret = 0;
    char arr_l7_set[ARR_L7_SET_MAX_LEN];
    char arr_l7_set_tmp[ARR_L7_SET_MAX_LEN];
    char arr_file_tmp[ARR_FILE_TMP_MAX_LEN];

    //获取l7_settings
    snprintf(arr_l7_set,sizeof(arr_l7_set),"%s:%s",ip_proto?FR_L4PROTO2STR(ip_proto):"any",l7_proto);
    //构建临时文件文件名
    snprintf(arr_file_tmp,sizeof(arr_file_tmp),"%s_tmp2",APM_CFG_FILENAME_ANALYZER);
    //判断临时文件是否存在  如果存在
    if(access(arr_file_tmp,W_OK) == 0)
    {
        //临时文件存在但没KEY
        i_ret = frconfig_get_string(arr_file_tmp,APM_ANALYZER_KEY_L7_DEFAULT,&p_value);
        if(i_ret != APM_FRCONFIG_SUCC)
        {
            //在L7set最后加入可使用的内存大小
            snprintf(&arr_l7_set[strlen(arr_l7_set)],ARR_L7_SET_MAX_LEN - strlen(arr_l7_set),":%d",i_mem_size);
            i_ret = __l7default_add_file_no_exist(arr_l7_set);
            return i_ret;
        }
        if(strstr(p_value,arr_l7_set))
        {
            frfree(p_value);
            return FR_SUCC;
        }
        //如果ip_proto为any
        snprintf(arr_l7_set_tmp,sizeof(arr_l7_set_tmp),"%s:%s","any",l7_proto);
        if(strstr(p_value,arr_l7_set_tmp))
        {
            frfree(p_value);
            return FR_SUCC;
        }
        //临时文件不存在该配置
        //在L7set最后加入可使用的内存大小
        snprintf(&arr_l7_set[strlen(arr_l7_set)],ARR_L7_SET_MAX_LEN - strlen(arr_l7_set),":%d",i_mem_size);

        i_ret = __l7default_add_file_exist(p_value,arr_l7_set);
        frfree(p_value);
        return i_ret;
    }
    //临时文集不存在
    i_ret = frconfig_get_string(APM_CFG_FILENAME_ANALYZER,APM_ANALYZER_KEY_L7_DEFAULT,&p_value);
    //如果原配置文件不存在 或者原文件中不含APM_ANALYZER_KEY_L7_DEFAULT
    if(i_ret != APM_FRCONFIG_SUCC)
    {
        i_ret = __l7default_add_file_no_exist(arr_l7_set);
        return i_ret;
    }

    //原配置文件中存在APM_ANALYZER_KEY_L7_DEFAULT
    //检查是否存在该配置
    if(strstr(p_value,arr_l7_set))
    {
        frfree(p_value);
        return FR_SUCC;
    }
    //如果ip_proto为any
    snprintf(arr_l7_set_tmp,sizeof(arr_l7_set_tmp),"%s:%s","any",l7_proto);
    if(strstr(p_value,arr_l7_set_tmp))
    {
        frfree(p_value);
        return FR_SUCC;
    }
    //在L7set最后加入可使用的内存大小
    snprintf(&arr_l7_set[strlen(arr_l7_set)],ARR_L7_SET_MAX_LEN - strlen(arr_l7_set),":%d",i_mem_size);
    i_ret = __l7default_add_file_exist(p_value,arr_l7_set);
    frfree(p_value);

    return i_ret;
}


static int __l7_default_del(int ip_proto)
{
    char *p_value = NULL;
    FILE *fp = NULL;
    int i_ret = 0;
    char arr_l7_set[ARR_L7_SET_MAX_LEN];
    char arr_file_tmp[ARR_FILE_TMP_MAX_LEN];
    char *p_tmp = NULL;
    char *p = NULL;

    //获取l7_settings
    snprintf(arr_l7_set,sizeof(arr_l7_set),"%s",ip_proto?FR_L4PROTO2STR(ip_proto):"any");

    //构建临时文件文件名
    snprintf(arr_file_tmp,sizeof(arr_file_tmp),"%s_tmp2",APM_CFG_FILENAME_ANALYZER);
    //判断临时文件是否存在  如果存在
    if(access(arr_file_tmp,W_OK) == 0)
    {
        i_ret = frconfig_get_string(arr_file_tmp,APM_ANALYZER_KEY_L7_DEFAULT,&p_value);
        //printf("\n%s\n",p_value);
        if(i_ret != APM_FRCONFIG_SUCC || *p_value =='\0')
        {
            if(p_value)
                frfree(p_value);
            return FR_SUCC;
        }

        p_tmp = strstr(p_value,arr_l7_set);
        if(!p_tmp)
        {
            frfree(p_value);
            return FR_SUCC;
        }
        //printf("\n%s\n",p_tmp);
        while(p_tmp)
        {
            //要删除的规则之后的字符串往前移，覆盖要删除的规则
            p = strchr(p_tmp,';');
            p = p? (p+1):(p_tmp + strlen(p_tmp));
            memmove(p_tmp, p, strlen(p) + 1);
            p_tmp = strstr(p_value,arr_l7_set);
        }
        fp = fopen(arr_file_tmp,"w");
        if(!fp)
        {
            frfree(p_value);
            return FR_FAIL;
        }
        fprintf(fp,"%s=%s",APM_ANALYZER_KEY_L7_DEFAULT,p_value);
        frfree(p_value);
        fclose(fp);
        return FR_SUCC;
    }

    //临时文件不存在
    //如果原配置文件存在 则获取原文件中的value值
    i_ret = frconfig_get_string(APM_CFG_FILENAME_ANALYZER,APM_ANALYZER_KEY_L7_DEFAULT,&p_value);
    if(i_ret != APM_FRCONFIG_SUCC)
        return FR_SUCC;

    p_tmp = strstr(p_value,arr_l7_set);
    if(!p_tmp)
    {
        frfree(p_value);
        return FR_SUCC;
    }
    while(p_tmp)
    {
        //要删除的规则之后的字符串往前移，覆盖要删除的规则
        p = strchr(p_tmp,';');
        p = p? (p+1):(p_tmp + strlen(p_tmp));
        memmove(p_tmp, p, strlen(p) + 1);
        p_tmp = strstr(p_value,arr_l7_set);
        p_tmp = strstr(p_value,arr_l7_set);
    }

    fp = fopen(arr_file_tmp,"w");
    if(!fp)
    {
        frfree(p_value);
        return FR_FAIL;
    }
    fprintf(fp,"%s=%s",APM_ANALYZER_KEY_L7_DEFAULT,p_value);
    frfree(p_value);
    fclose(fp);
    return FR_SUCC;
}

static int __l7_default_clear(void)
{
    int i_ret = 0;
    char arr_file_tmp[ARR_FILE_TMP_MAX_LEN];
    FILE *fp = NULL;
    //构建临时文件名
    snprintf(arr_file_tmp, ARR_FILE_TMP_MAX_LEN, "%s_tmp2", APM_CFG_FILENAME_ANALYZER);
    //如果临时文件不存在，则建立一个空文件
    if(access(arr_file_tmp,W_OK) == -1)
    {
        fp = fopen(arr_file_tmp,"w");
        fclose(fp);
    }
    i_ret = frconfig_set_string(arr_file_tmp,APM_ANALYZER_KEY_L7_DEFAULT,"\0");
    return i_ret;
}

int do_l7default_cmd(Command *p_command)
{
    L7Default *l7_default = p_command->l7_default;
    L7Setting *l7_settings = l7_default->l7_settings[0];
    char *p_action = l7_default->action;
    int i_ret = 0;

    if (p_action == NULL || l7_settings == NULL)
        return FR_FAIL;

    if (strncasecmp(p_action, "add", strlen("add")) == 0)
    {
        frdbg("__do_l7default_add start\n");
        i_ret = __l7_default_add(l7_settings->ip_proto,l7_settings->l7_proto,l7_default->mem_size);
        return i_ret;
    }
    else if (strncasecmp(p_action, "del", strlen("del")) == 0)
    {
        frdbg("__do_l7default_del start\n");
        i_ret = __l7_default_del(l7_settings->ip_proto);
        return i_ret;
    }
    else if (strncasecmp(p_action, "clear", strlen("clear")) == 0)
    {
        frdbg("__l7_default_clear start\n");
        i_ret = __l7_default_clear();
        return i_ret;
    }

    return FR_FAIL;
}

static int __module_add_file_no_exist(char *p_module_set)
{
    char arr_file_tmp[ARR_FILE_TMP_MAX_LEN];
    FILE *fp = NULL;
    //构建临时文件文件名
    snprintf(arr_file_tmp,sizeof(arr_file_tmp),"%s_tmp3",APM_CFG_FILENAME_ANALYZER);

    fp = fopen(arr_file_tmp,"w");
    if(!fp)
        return FR_FAIL;
    fprintf(fp,"%s=%s",APM_ANALYZER_KEY_MODULE_LOAD,p_module_set);
    fclose(fp);
    return FR_SUCC;
}

static int __module_add_file_exist(char *p_value, char *p_module_set)
{
    char arr_file_tmp[ARR_FILE_TMP_MAX_LEN];
    char *p_value_tmp = NULL;
    FILE *fp = NULL;

    //判断最后一位是否为";"
    if(*p_value !='\0' && *(p_value + strlen(p_value) - 1) == ';')
    {
        p_value_tmp = frmalloc(strlen(p_value) + strlen(p_module_set) + 1);
        if(!p_value_tmp)
            return FR_FAIL;
        snprintf(p_value_tmp,strlen(p_value) + strlen(p_module_set) + 1,"%s%s",p_value,p_module_set);
    }
    else
    {
        if(*p_value!='\0')
        {
            p_value_tmp = frmalloc(strlen(p_value) + strlen(p_module_set) + 1 + 1);
            if(!p_value_tmp)
                return FR_FAIL;
            snprintf(p_value_tmp,strlen(p_value) + strlen(p_module_set) + 1 + 1,"%s;%s",p_value,p_module_set);
        }
        else
        {
            p_value_tmp = frmalloc(strlen(p_module_set) + 1);
            if(!p_value_tmp)
                return FR_FAIL;
            snprintf(p_value_tmp, strlen(p_module_set) + 1,"%s",p_module_set);
        }
    }
    //构建临时文件文件名
    snprintf(arr_file_tmp,sizeof(arr_file_tmp),"%s_tmp3",APM_CFG_FILENAME_ANALYZER);
    fp = fopen(arr_file_tmp,"w");
    if(fp == NULL)
        return FR_FAIL;

    fprintf(fp,"%s=%s", APM_ANALYZER_KEY_MODULE_LOAD, p_value_tmp);
    frfree(p_value_tmp);
    fclose(fp);

    return FR_SUCC;
}


static int __module_add(char *p_path, char *l4_proto, int l7_proto, char *p_l7_proto_name,int i_mem_size)
{
    char *p_value = NULL;
    int i_ret = 0;
    char arr_module_set[ARR_MODULE_SET_MAX_LEN];
    char arr_file_tmp[ARR_FILE_TMP_MAX_LEN];

    //获取arr_module_set
    snprintf(arr_module_set,sizeof(arr_module_set),"%s:%s:%d:%s:%d",p_path,l4_proto,l7_proto,p_l7_proto_name,i_mem_size);

    //构建临时文件文件名
    snprintf(arr_file_tmp,sizeof(arr_file_tmp),"%s_tmp3",APM_CFG_FILENAME_ANALYZER);
    //判断临时文件是否存在  如果存在
    if(access(arr_file_tmp,W_OK) == 0)
    {
        //临时文件存在但没KEY
        i_ret = frconfig_get_string(arr_file_tmp,APM_ANALYZER_KEY_MODULE_LOAD,&p_value);
        if(i_ret != APM_FRCONFIG_SUCC)
        {
            i_ret = __module_add_file_no_exist(arr_module_set);
            return i_ret;
        }
        //p_value不为空  临时文件已存在该配置内容
        if(strstr(p_value,arr_module_set))
        {
            frfree(p_value);
            return FR_SUCC;
        }

        i_ret = __module_add_file_exist(p_value,arr_module_set);
        frfree(p_value);
        return i_ret;
    }

    i_ret = frconfig_get_string(APM_CFG_FILENAME_ANALYZER,APM_ANALYZER_KEY_MODULE_LOAD,&p_value);
    if(i_ret != APM_FRCONFIG_SUCC)
    {
        i_ret = __module_add_file_no_exist(arr_module_set);
        return i_ret;
    }
    //p_value不为空  临时文件已存在该配置内容
    if(strstr(p_value,arr_module_set))
    {
        frfree(p_value);
        return FR_SUCC;
    }

    i_ret = __module_add_file_exist(p_value,arr_module_set);
    frfree(p_value);
    return i_ret;
}


static int __module_del(int l7_proto)
{
    char *p_value = NULL;
    FILE *fp = NULL;
    int i_ret = 0;
    char arr_module_set[ARR_MODULE_SET_MAX_LEN];
    char arr_file_tmp[ARR_FILE_TMP_MAX_LEN];
    char *p_tmp = NULL;
    char *p = NULL;

    //获取arr_module_set
    snprintf(arr_module_set,sizeof(arr_module_set),"%d",l7_proto);

    //构建临时文件文件名
    snprintf(arr_file_tmp,sizeof(arr_file_tmp),"%s_tmp3",APM_CFG_FILENAME_ANALYZER);
    //判断临时文件是否存在  如果存在
    if(access(arr_file_tmp,W_OK) == 0)
    {
        //临时文件存在但没KEY
        i_ret = frconfig_get_string(arr_file_tmp,APM_ANALYZER_KEY_MODULE_LOAD,&p_value);
        if(i_ret != APM_FRCONFIG_SUCC || *p_value =='\0')
        {
            if(p_value)
                frfree(p_value);

            return FR_SUCC;
        }

        p_tmp = strstr(p_value,arr_module_set);
        if(!p_tmp)
        {
            frfree(p_value);
            return FR_SUCC;
        }
        //printf("\n%s\n",p_tmp);
        while(p_tmp)
        {
            //要删除的规则之后的字符串往前移，覆盖要删除的规则
            p = strchr(p_tmp,';');
            p = p? (p+1):(p_tmp + strlen(p_tmp));
            //查询前一条结尾的';'
            while(*p_tmp != ';' && (int)(p_tmp - p_value) > 0)
                p_tmp--;

            if(*p_tmp == ';')
                p_tmp++;

            memmove(p_tmp, p, strlen(p) + 1);
            p_tmp = strstr(p_value,arr_module_set);
        }
        fp = fopen(arr_file_tmp,"w");
        if(!fp)
        {
            frfree(p_value);
            return FR_FAIL;
        }
        fprintf(fp,"%s=%s",APM_ANALYZER_KEY_MODULE_LOAD,p_value);
        frfree(p_value);
        fclose(fp);
        return FR_SUCC;
    }

    i_ret = frconfig_get_string(APM_CFG_FILENAME_ANALYZER,APM_ANALYZER_KEY_MODULE_LOAD,&p_value);
    if(i_ret != APM_FRCONFIG_SUCC || *p_value =='\0')
    {
        if(p_value)
            frfree(p_value);
        return FR_SUCC;
    }

    p_tmp = strstr(p_value,arr_module_set);
    if(!p_tmp)
    {
        frfree(p_value);
        return FR_SUCC;
    }
    //printf("\n%s\n",p_tmp);
    while(p_tmp)
    {
        //要删除的规则之后的字符串往前移，覆盖要删除的规则
        p = strchr(p_tmp,';');
        p = p? (p+1):(p_tmp + strlen(p_tmp));
        //查询前一条结尾的';'
        while(*p_tmp != ';' && (int)(p_tmp - p_value) > 0)
            p_tmp--;

        if(*p_tmp == ';')
            p_tmp++;

        memmove(p_tmp, p, strlen(p) + 1);
        p_tmp = strstr(p_value,arr_module_set);
    }
    fp = fopen(arr_file_tmp,"w");
    if(!fp)
    {
        frfree(p_value);
        return FR_FAIL;
    }
    fprintf(fp,"%s=%s",APM_ANALYZER_KEY_MODULE_LOAD,p_value);
    frfree(p_value);
    fclose(fp);
    return FR_SUCC;
}

static int __module_clear(void)
{
    int i_ret = 0;
    char arr_file_tmp[ARR_FILE_TMP_MAX_LEN];
    FILE *fp = NULL;

    //构建临时文件名
    snprintf(arr_file_tmp, ARR_FILE_TMP_MAX_LEN, "%s_tmp3", APM_CFG_FILENAME_ANALYZER);
    //如果临时文件不存在，则建立一个空文件
    if(access(arr_file_tmp,W_OK) == -1)
    {
        fp = fopen(arr_file_tmp,"w");
        fclose(fp);
    }

    i_ret = frconfig_set_string(arr_file_tmp,APM_ANALYZER_KEY_MODULE_LOAD,"\0");
    return i_ret;
}

int do_module_cmd(Command *p_command)
{
    ModuleCommand *p_module_cmd = p_command->module_cmd;
    char *p_action = p_module_cmd->action;
    int i_ret = 0;

    if (p_action == NULL)
        return FR_FAIL;

    if (strncasecmp(p_action, "add", strlen("add")) == 0)
    {
        frdbg("__module_add start\n");
        i_ret = __module_add(p_module_cmd->so_path, FR_L4PROTO2STR(p_module_cmd->l4_proto), p_module_cmd->l7_proto, p_module_cmd->l7_protoname, p_module_cmd->mem_size);
        return i_ret;
    }
    else if (strncasecmp(p_action, "del", strlen("del")) == 0)
    {
        frdbg("__module_del start\n");
        i_ret = __module_del(p_module_cmd->l7_proto);
        return i_ret;
    }
    else if (strncasecmp(p_action, "clear", strlen("clear")) == 0)
    {
        frdbg("__module_clear start\n");
        i_ret = __module_clear();
        return i_ret;
    }
    else
        return FR_FAIL;
}

